{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Backed by a Vector Store\n",
    "VectorStoreRetrieverMemory stores memories in a vector store and queries the top-K most \"salient\" docs every time it is called.\n",
    "\n",
    "VectorStoreRetrieverMemory 将内存存储在向量存储中，并在每次调用时查询前 K 个最“突出”的文档。\n",
    "\n",
    "This differs from most of the other Memory classes in that it doesn't explicitly track the order of interactions.\n",
    "\n",
    "这与大多数其他 Memory 类的不同之处在于它不显式跟踪交互的顺序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import OpenAIEmbeddings\n",
    "from langchain_openai import OpenAI\n",
    "from langchain.memory import VectorStoreRetrieverMemory\n",
    "from langchain.chains import ConversationChain\n",
    "from langchain_core.prompts import PromptTemplate\n",
    "\n",
    "import faiss\n",
    "\n",
    "from langchain_community.docstore import InMemoryDocstore\n",
    "from langchain_community.vectorstores import FAISS\n",
    "\n",
    "\n",
    "embedding_size = 1536 # Dimensions of the OpenAIEmbeddings\n",
    "index = faiss.IndexFlatL2(embedding_size)\n",
    "embedding_fn = OpenAIEmbeddings().embed_query\n",
    "vectorstore = FAISS(embedding_fn, index, InMemoryDocstore({}), {})\n",
    "# In actual usage, you would set `k` to be a higher value, but we use k=1 to show that\n",
    "# the vector lookup still returns the semantically relevant information\n",
    "retriever = vectorstore.as_retriever(search_kwargs=dict(k=1))\n",
    "memory = VectorStoreRetrieverMemory(retriever=retriever)\n",
    "\n",
    "# When added to an agent, the memory object can save pertinent information from conversations or used tools\n",
    "memory.save_context({\"input\": \"My favorite food is pizza\"}, {\"output\": \"that's good to know\"})\n",
    "memory.save_context({\"input\": \"My favorite sport is soccer\"}, {\"output\": \"...\"})\n",
    "memory.save_context({\"input\": \"I don't the Celtics\"}, {\"output\": \"ok\"}) #"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "llm = OpenAI(temperature=0) # Can be any valid LLM\n",
    "_DEFAULT_TEMPLATE = \"\"\"The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
    "\n",
    "Relevant pieces of previous conversation:\n",
    "{history}\n",
    "\n",
    "(You do not need to use these pieces of information if not relevant)\n",
    "\n",
    "Current conversation:\n",
    "Human: {input}\n",
    "AI:\"\"\"\n",
    "PROMPT = PromptTemplate(\n",
    "    input_variables=[\"history\", \"input\"], template=_DEFAULT_TEMPLATE\n",
    ")\n",
    "conversation_with_summary = ConversationChain(\n",
    "    llm=llm,\n",
    "    prompt=PROMPT,\n",
    "    memory=memory,\n",
    "    verbose=True\n",
    ")\n",
    "%time\n",
    "conversation_with_summary.predict(input=\"Hi, my name is Perry, what's up?\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain0_1",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
